home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-06-20 | 9.3 KB | 289 lines | [TEXT/PJMM] |
- { Fuzzy Balls FKEY © 1991 by Jon Wind }
- { Version 1.0 on 6/20/91 }
- {}
- { This FKEY is a poor man’s screen saver. It displays shaded balls in color, grays, or b&w, }
- { depending on the monitor. Approximately 60 circles are drawn per second. Random ball }
- { sizes are used unless the caps lock key is down. Every 15 seconds the screen the screen }
- { is cleared to black and a new ball size is randomly chosen (25-80 pixels). If the control }
- { key is down when the FKEY is called, ball shading is reversed. It should work correctly on }
- { any Mac, even on Macs that have b&w and color monitors. }
- {}
- { Thanks to Brad Pettit and his colorfkey for his method of conditional compilation. }
- {}
- { To execute this as a program... }
- { 1. change the definition of fkey to false }
- { 2. set the project type to application }
- { 3. change the library from drvrruntime.lib to µruntime.lib }
- { 4. rebuild the project }
-
-
- {$setc fkey := true}
-
- {$ifc fkey}
-
- unit BallsFKEY;
-
- interface
-
- uses
- Picker;
-
- procedure main;
-
- implementation
-
- {$elsec}
-
- program BallsFKEY;
-
-
- uses
- Picker;
-
- {$endc}
-
- procedure main;
- const
- bCommandKey = 48;
- bShiftKey = 63;
- bControlKey = 60;
- bOptionKey = 61;
- bCapsLockKey = 62;
- RawMouseGlobal = $82C;
- WNETrapNum = $60; { trap number of WaitNextEvent }
- UnImplTrapNum = $9F; { trap number of "unimplemented trap" }
- CreditTime = 180;
- WaitTime = 75; { number of ticks to wait before starting drawing balls }
- ClsTime = 900; { clear screen interval in ticks }
- minBall = 25;
- maxBall = 80;
- firstPat = 1;
- lastPat = 8;
- Line1 = 'Written by Jon Wind on 6/20/91.';
- Line2 = 'Press Caps Lock for static sizes.';
- Line3 = 'Launch with Control key to reverse shading.';
-
- var
- ballwidth, i, x, patAdjust: Integer;
- iconRect, scrnRect: Rect;
- savePort: GrafPtr;
- oldmouseLoc, oldTicks, lastCls, L: LongInt;
- Credits, hasColor, multiBit, useColor, wakeup, WNE: Boolean;
- theEvent: EventRecord;
- w: WindowPtr;
- region: RgnHandle;
- patArray: array[firstPat..lastPat] of pattern;
- deviceHdl: GDHandle;
- theHSV: HSVColor;
- theRGB: RGBColor;
-
-
- function GetLRandom (min, max: Longint): Longint;
- { return a random number within a given range }
- var
- y: Longint;
- begin
- y := min;
- if min < max then
- repeat
- y := random;
- y := (((y + maxint) * max) div 16383) + min;
- until (y >= min) & (y <= max);
- GetLRandom := y;
- end; { of func GetLRandom }
-
- function GetKeyDown (index: Integer): Boolean;
- { return the stae of the desired key - true if down; false if up }
- var
- keys: keymap;
- begin
- GetKeys(keys);
- GetKeyDown := bittst(@keys, index); { look at entry within the key map }
- end;
-
- procedure Check4Color (var hasColor, multiBit: Boolean);
- { hasColor = true if using 4 or more "colors", multiBit = true if colorDevices <> totalDevices }
- var
- deviceHdl: GDHandle;
- theWorld: SysEnvRec;
- totalDevices, colorDevices: Integer;
- begin
- colorDevices := 0; { assume no color devices }
- totalDevices := 0; { assume no devices }
- if (SysEnvirons(1, theWorld) <> envNotPresent) then { SysEnvirons call is available }
- if theWorld.hasColorQD then { has Color QuickDraw }
- begin
- deviceHdl := GetDeviceList;
- repeat
- if deviceHdl <> nil then
- begin
- totalDevices := Succ(totalDevices);
- if (deviceHdl^^.gdPMap^^.pixelsize > 1) then { 4 or more shades? }
- colorDevices := Succ(colorDevices);
- end;
- deviceHdl := GetNextDevice(deviceHdl);
- until deviceHdl = nil;
- end;
- multiBit := (colorDevices <> totalDevices);
- hasColor := (colorDevices > 0);
- end;{ of proc Check4Color }
-
- function myGetGrayRgn: Handle;
- { get current gray region }
- var
- thePtr: ^Handle;
- begin
- thePtr := Pointer($9EE);
- myGetGrayRgn := thePtr^;
- end; { of func GetGrayRgn }
-
- function GetRawMouse: LongInt;
- { get current mouse location }
- var
- thePtr: ^LongInt;
- begin
- thePtr := Pointer(RawMouseGlobal);
- GetRawMouse := thePtr^;
- end; { of func GetRawMouse }
-
-
- { --------- Main Procedure --------- }
- begin
- GetPort(savePort); { save current grafport }
-
- WNE := NGetTrapAddress(WNETrapNum, ToolTrap) <> NGetTrapAddress(UnImplTrapNum, ToolTrap);
-
- theHSV.value := 50000; { use darker colors }
- theHSV.saturation := -1;
-
- { create "magic" shading patterns }
- StuffHex(@patArray[1], '77FFDDFF57FFDDFF');
- StuffHex(@patArray[2], '55FFDDFF55FF5DFF');
- StuffHex(@patArray[3], '55BF55FF55FB55FF');
- StuffHex(@patArray[4], '55EE55BB55EE55BA');
- StuffHex(@patArray[5], '5599556A559955A6');
- StuffHex(@patArray[6], '5598552255895522');
- StuffHex(@patArray[7], 'AA40AA00AA04AA00');
- StuffHex(@patArray[8], '0045001100540011');
-
- oldmouseLoc := GetRawMouse;
- Check4Color(hasColor, multiBit); { determine whether there's one or more color monitors running in color }
- if GetKeyDown(bControlKey) then
- patAdjust := 9
- else
- patAdjust := 0;
-
- region := NewRgn;
- CopyRgn(RgnHandle(myGetGrayRgn), region); { get total screen area including menu bar }
- scrnRect := region^^.rgnBBox;
- if (scrnRect.top > 0) then
- scrnRect.top := 0;
-
- if hascolor then
- w := NewCWindow(nil, scrnRect, '', True, altDBoxProc, Pointer(-1), False, 0)
- else
- w := NewWindow(nil, scrnRect, '', True, altDBoxProc, Pointer(-1), False, 0);
-
- RectRgn(region, w^.portRect);
- UnionRgn(region, w^.visRgn, w^.visRgn); { I want to cover everything, including the menu bar }
- DisposeRgn(region); { don't need it any more… }
-
- SetPort(w); { set as current port }
- ClipRect(scrnRect);
- PaintRect(scrnRect);
- LastCls := TickCount; { set to current "time" }
-
- ObscureCursor;
-
- Credits := True; { I'm going to show a brief credits message… }
- TextMode(srcBic); { white credits text on black background… }
- MoveTo(40, 50);
- DrawString(Line1);
- MoveTo(40, 70);
- DrawString(Line2);
- MoveTo(40, 90);
- DrawString(Line3);
-
- Delay(WaitTime, L); { delay to allow keys to be released and message to be read }
-
- repeat
- oldTicks := TickCount; { store current "time" }
-
- if not Credits then
- begin
- if (TickCount - LastCls > ClsTime) then
- begin
- ballwidth := GetLRandom(minBall, maxBall); { generate new ball width with each screen clear }
- PenNormal;
- PaintRect(scrnRect);
- lastCls := TickCount; { get time of last screen clear }
- end;
-
- if not GetKeyDown(bCapsLockKey) then
- ballwidth := GetLRandom(minBall, maxBall); { generate new ball width if caps lock is up - not down! }
-
- iconRect.top := GetLRandom(scrnRect.top - BSR(ballwidth, 1), scrnRect.bottom); { guarantee clipping on screen top }
- iconRect.left := GetLRandom(scrnRect.left - BSR(ballwidth, 1), scrnRect.right); { guarantee clipping on screen left }
- iconRect.right := iconRect.left + ballwidth; { make rectangle a square }
- iconRect.bottom := iconRect.top + ballwidth; { make rectangle a square }
-
- usecolor := hasColor;
- if hasColor & multiBit then { must check depth of screen - may be B&W }
- begin
- LocalToGlobal(iconRect.topLeft);
- LocalToGlobal(iconRect.botRight);
- deviceHdl := GetMaxDevice(iconRect); { get deepest device covered by rect }
- useColor := (deviceHdl <> nil) & (deviceHdl^^.gdPMap^^.pixelsize > 2);
- end;
- if useColor then { generate random rgb color }
- begin
- theHSV.hue := GetLRandom(0, 65535);
- HSV2RGB(theHSV, theRGB);
- RGBBackColor(theRGB);
- end;
-
- { use patterns to draw shaded balls }
- x := BSR(ballwidth div Succ(lastPat), 1);
- for i := firstPat to lastPat do
- begin
- PenPat(patArray[Abs(patAdjust - i)]);
- PaintOval(iconRect);
- InsetRect(iconRect, x, x);
- iconRect.bottom := iconRect.bottom - x;
- iconRect.right := iconRect.right - x;
- end;
-
- end
- else if (TickCount - LastCls > CreditTime) then { past time when credits should be displayed - only executes once }
- begin
- Credits := False; { indicate credits no longer need to be displayed }
- LastCls := 0; { set to 0 to force a screen clear, set ball width, etc. }
- end;
-
- repeat
- if WNE then
- wakeup := WaitNextEvent(mDownMask + keyDownMask + diskMask, theEvent, 1, nil) { an event... }
- else
- wakeup := GetNextEvent(mDownMask + keyDownMask + diskMask, theEvent); { if there's an event... }
- if wakeup then { make sure it's an event we want... }
- wakeup := (theEvent.what = mouseDown) or (theEvent.what = keyDown) or (theEvent.what = diskEvt);
- until wakeup or (TickCount > oldTicks); { effectively limits drawing speed to approx. one ball per tick }
- until wakeup or (oldmouseLoc <> GetRawMouse) or GetKeyDown(bOptionKey) or GetKeyDown(bCommandKey) or GetKeyDown(bShiftKey) or GetKeyDown(bControlKey);
-
- PenNormal;
- PaintRect(scrnRect);
- DisposeWindow(w); { don't need it any more… }
- SetPort(savePort); { restore previous grafport }
- InitCursor; { restore cursor - and probably piss off the current app if it wasn't using the arrow… }
- DrawMenuBar; { fix menubar }
- end; { main }
-
-
- {$ifc fkey = false}
-
- begin
- main;
-
- {$endc}
-
- end.